using System;
using System.Collections.Generic;
using System.Text;
using BizTalkCop.Rules.Bases;
using Microsoft.FxCop.Sdk;
using Microsoft.XLANGs.BaseTypes;
using Microsoft.BizTalk.XLANGs.BTXEngine;
using Microsoft.BizTalk.PipelineOM;

namespace BizTalkCop.Rules.Naming.Rules
{
    /// <summary>
    /// Rule verifying artifacts are declared in the relevant namespace
    /// </summary>
    public class ArtifactsShouldBeDeclaredInTheCorrectModule : RuleBase
    {
        /// <summary>
        /// Default constructor
        /// </summary>
        public ArtifactsShouldBeDeclaredInTheCorrectModule() : base("ArtifactsShouldBeDeclaredInTheCorrectModule") { }

        private static Dictionary<Type, string> _suffixes;
        private static Dictionary<Type, string> Suffixes
        {
            get
            {
                if (_suffixes == null)
                {
                    _suffixes = new Dictionary<Type, string>();
                    _suffixes.Add(typeof(TransformBase), ".Transforms");
                    _suffixes.Add(typeof(SchemaBase), ".Schemas");
                    _suffixes.Add(typeof(BTXService), ".Orchestrations");
                    _suffixes.Add(typeof(SendPipeline), ".Pipelines");
                    _suffixes.Add(typeof(ReceivePipeline), ".Pipelines");
                }
                return _suffixes;
            }
        }

        /// <summary>
        /// Checks if the namespace of the type is correct
        /// </summary>
        /// <param name="type">Type to check</param>
        /// <returns>Problem collection</returns>
        public override ProblemCollection Check(TypeNode type)
        {
            foreach (KeyValuePair<Type, string> suffix in Suffixes)
            {
                if (IsChildOfType(type, suffix.Key) && !type.DeclaringModule.Name.EndsWith(suffix.Value))
                {
                    Problems.Add(new Problem(GetNamedResolution("Suffix", string.Format("{0}{1}", type.DeclaringModule.Name, suffix.Value)), type));
                    break;
                }
            }
            return Problems;
        }
    }
}
